package com.jwsoft.manager.core.integration.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.extra.servlet.ServletUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.bifang.assistant.common.vo.BaseVO;
import com.bifang.engine.assistant.core.annotation.ApiService;
import com.bifang.engine.assistant.core.annotation.OpApi;
import com.bifang.engine.assistant.core.annotation.SaveOplog;
import com.bifang.engine.assistant.core.enums.AuTypeEnum;
import com.bifang.engine.assistant.core.enums.BoolEnum;
import com.bifang.engine.assistant.core.enums.FuncTypeEnum;
import com.bifang.engine.assistant.core.exception.AppException;
import com.bifang.engine.assistant.core.utils.SessionUtil;
import com.bifang.engine.cache.redis.RedisHelper;
import com.bifang.engine.data.core.util.PagerUtil;
import com.bifang.engine.protect.core.annotation.NoSignCrypto;
import com.bifang.module.base.common.vo.common.CommonVO;
import com.bifang.module.base.common.vo.dict.DictAreaVO;
import com.bifang.module.base.common.vo.dict.SelectVO;
import com.bifang.module.base.common.vo.excel.ExcelModelVO;
import com.bifang.module.base.common.vo.excel.ExcelVO;
import com.bifang.module.base.core.helper.DictHelper;
import com.bifang.module.base.core.helper.ExcelCommonHelper;
import com.bifang.module.base.core.integration.CommonIntegration;
import com.bifang.module.base.core.integration.DictIntegration;
import com.bifang.module.base.core.integration.ExcelIntegration;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.jwsoft.manager.common.enums.CardTypeEnum;
import com.jwsoft.manager.common.enums.EnrollStatusFormalEnum;
import com.jwsoft.manager.common.enums.SchoolCategoryEnum;
import com.jwsoft.manager.common.enums.SyncZjApplyEnum;
import com.jwsoft.manager.common.vo.common.recruitStudent.EduSyncZjApplyReq;
import com.jwsoft.manager.common.vo.common.recruitStudent.RecruitStudentSyncRetVO;
import com.jwsoft.manager.common.vo.common.recruitStudent.SyncStudentQueryVO;
import com.jwsoft.manager.common.vo.common.recruitStudent.SyncStudentVO;
import com.jwsoft.manager.common.vo.eduSchool.EduSchoolVO;
import com.jwsoft.manager.common.vo.eduSyncZjApply.EduSyncZjApplyKeyVO;
import com.jwsoft.manager.common.vo.eduSyncZjApply.EduSyncZjApplyQueryVO;
import com.jwsoft.manager.common.vo.eduSyncZjApply.EduSyncZjApplyVO;
import com.jwsoft.manager.common.vo.eduSyncZjApprove.EduSyncZjApproveQueryVO;
import com.jwsoft.manager.common.vo.eduSyncZjApprove.EduSyncZjApproveVO;
import com.jwsoft.manager.common.vo.eduSyncZjDelete.EduSyncZjDeleteQueryVO;
import com.jwsoft.manager.common.vo.eduSyncZjEnroll.EduSyncZjEnrollQueryVO;
import com.jwsoft.manager.common.vo.eduSyncZjEnroll.EduSyncZjEnrollVO;
import com.jwsoft.manager.core.dao.model.*;
import com.jwsoft.manager.core.dao.service.*;
import com.jwsoft.manager.core.integration.EduSyncZjApplyIntegration;
import com.jwsoft.manager.core.integration.EduSyncZjApproveIntegration;
import com.jwsoft.manager.core.integration.EduSyncZjEnrollIntegration;
import com.jwsoft.manager.core.util.EduHelper;
import com.jwsoft.manager.core.util.EduSyncZjUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.scheduling.annotation.Async;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import javax.servlet.http.HttpServletResponse;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 省招生报名专库同步管理业务实现类
 *
 * @author chenzh
 * @since 2023-07-25
 */
@ApiService(funcCode = "eduSyncZj", title = "省招生报名专库同步管理")
@Slf4j
public class EduSyncZjApplyIntegrationImpl implements EduSyncZjApplyIntegration {

    @Autowired
    public EduSyncZjApplyService eduSyncZjApplyService;
    @Autowired
    private EduSyncZjApproveService approveService;
    @Autowired
    private EduHelper eduHelper;
    @Autowired
    private EduSyncZjUtil eduSyncZjUtil;
    @Autowired
    private CommonIntegration commonIntegration;
    @Autowired
    private RedisHelper redisHelper;
    @Autowired
    private DictHelper dictHelper;
    @Autowired
    private DictIntegration dictIntegration;
    @Autowired
    private EduStudentEnrollService eduStudentEnrollService;
    @Autowired
    private EduSyncZjEnrollService syncZjEnrollService;
    @Autowired
    private EduSyncZjDeleteService syncZjDeleteService;
    @Autowired
    private EduSchoolService schoolService;

    @Autowired
    private ExcelIntegration excelIntegration;

    @Autowired
    private EduSyncZjApproveIntegration approveIntegration;

    @Autowired
    private EduSyncZjEnrollIntegration eduSyncZjEnrollIntegration;

    @Autowired
    private ExcelCommonHelper excelCommonHelper;
    @Value("${spring.servlet.multipart.location}")
    private String tempPath;


    @Override
    @OpApi(funcCode = "eduSyncZj0001", title = "省招生报名专库同步管理-报名数据同步分页查询", funcType = FuncTypeEnum.query)
    public PageInfo<EduSyncZjApplyVO> getList(EduSyncZjApplyQueryVO vo) {
        // 开启分页
        if (vo.getPageNum() == null || vo.getPageSize() == null) {
            //如果不传入分页参数，默认最大取1000条
            vo.setPageNum(1);
            vo.setPageSize(1000);
        }
        if (vo.getTheYear() == null) {
            vo.setTheYear(eduHelper.thisYear());
        }
        List<String> areaCodeList = new ArrayList<>();
        if (CollectionUtils.isEmpty(areaCodeList)){
            if (ObjectUtils.isEmpty(vo.getApplyCountyCode())){
                List<SelectVO> selectVOList = dictIntegration.getDistrictByOrg(new DictAreaVO());
                areaCodeList = selectVOList.stream()
                        .map(SelectVO::getDictKey)
                        .collect(Collectors.toList());
                String sessionAreaCode = SessionUtil.getAreaCode();
                if (!areaCodeList.contains(sessionAreaCode)) {
                    areaCodeList.add(sessionAreaCode);
                }
            }
        }
        QueryWrapper<EduSyncZjApply> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                .eq(StringUtils.isNotBlank(vo.getIdNumber()), EduSyncZjApply::getIdNumber, vo.getIdNumber())
                .like(StringUtils.isNotBlank(vo.getName()), EduSyncZjApply::getName, vo.getName())
                .eq(StringUtils.isNotBlank(vo.getIdType()), EduSyncZjApply::getIdType, vo.getIdType())
                .eq(vo.getTheYear() != null, EduSyncZjApply::getTheYear, vo.getTheYear())
                .eq(StringUtils.isNotBlank(vo.getBusinessCode()), EduSyncZjApply::getBusinessCode, vo.getBusinessCode())
                .eq(StringUtils.isNotBlank(vo.getSex()), EduSyncZjApply::getSex, vo.getSex())
                .eq(StringUtils.isNotBlank(vo.getStage()), EduSyncZjApply::getStage, vo.getStage())
                .eq(StringUtils.isNotBlank(vo.getSyncStatus()), EduSyncZjApply::getSyncStatus, vo.getSyncStatus())
                .eq(StringUtils.isNotBlank(vo.getMasterGuardianNumber()), EduSyncZjApply::getMasterGuardianNumber, vo.getMasterGuardianNumber())
                .eq(StringUtils.isNotBlank(vo.getMasterGuardianName()), EduSyncZjApply::getMasterGuardianName, vo.getMasterGuardianName())
                .eq(StringUtils.isNotBlank(vo.getSlaveGuardianName()), EduSyncZjApply::getSlaveGuardianName, vo.getSlaveGuardianName())
                .eq(StringUtils.isNotBlank(vo.getSlaveGuardianNumber()), EduSyncZjApply::getSlaveGuardianNumber, vo.getSlaveGuardianNumber());
        if (!CollectionUtils.isEmpty(areaCodeList)){
            queryWrapper.lambda().in(EduSyncZjApply::getApplyCountyCode, areaCodeList);
        }else{
            queryWrapper.lambda().eq(EduSyncZjApply::getApplyCountyCode, vo.getApplyCountyCode());
        }
        queryWrapper.lambda().orderByDesc(EduSyncZjApply::getUpdateTime,EduSyncZjApply::getCreateTime);
        PageHelper.startPage(vo.getPageNum(), vo.getPageSize());
        List<EduSyncZjApply> list = eduSyncZjApplyService.list(queryWrapper);
        if (CollectionUtils.isEmpty(list)) {
            // 判断是否为空，为空则返回空参数
            return PagerUtil.createEmptyPagerInfo(vo.getPageNum(), vo.getPageSize());
        }
        // 不为空则获取分页结果
        PageInfo<EduSyncZjApply> pageInfo = new PageInfo<>(list);
        // 返回参数需要通过common层的vo实体类，用该方法可以批量转换
        List<EduSyncZjApplyVO> resultList = Convert.toList(EduSyncZjApplyVO.class, pageInfo.getList());
        // 转义数据字典值
        dictHelper.valueToName(resultList, Arrays.asList(SyncZjApplyEnum.values()));
        return PagerUtil.parsePagerVo(resultList, pageInfo);
    }

    @Override
    @OpApi(funcCode = "eduSyncZj0002", title = "省招生报名专库同步管理-报名数据同步根据主键查询详情", funcType = FuncTypeEnum.query)
    public EduSyncZjApplyVO getById(EduSyncZjApplyKeyVO vo) {
        EduSyncZjApply entity = eduSyncZjApplyService.getById(vo.getZjApplyId());
        if (ObjectUtils.isEmpty(entity)) {
            throw new AppException("查询不到详细信息!");
        }
        EduSyncZjApplyVO result = Convert.convert(EduSyncZjApplyVO.class, entity);
        return result;
    }

    @Override
    @OpApi(funcCode = "eduSyncZj0004", title = "省招生报名专库同步管理-报名数据同步新增", funcType = FuncTypeEnum.insert)
    @SaveOplog(
            operationType = "eduSyncZj0004",
            operationName = "省招生报名专库同步管理-报名数据同步新增",
            dataType = "zjApplyId",
            auType = AuTypeEnum.OTHER)
    @Transactional
    public EduSyncZjApplyVO add(EduSyncZjApplyVO vo) {
        //保存前校验
        //保存数据
        EduSyncZjApply entity = Convert.convert(EduSyncZjApply.class, vo);
        eduSyncZjApplyService.save(entity);
        //将主键设置回vo使操作日志可以取到
        vo.setZjApplyId(entity.getZjApplyId());
        return vo;
    }

    @Override
    @OpApi(funcCode = "eduSyncZj0005", title = "省招生报名专库同步管理-报名数据同步修改", funcType = FuncTypeEnum.update)
    @SaveOplog(
            operationType = "eduSyncZj0005",
            operationName = "省招生报名专库同步管理-报名数据同步修改",
            dataType = "zjApplyId",
            auType = AuTypeEnum.OTHER)
    @Transactional
    public EduSyncZjApplyVO edit(EduSyncZjApplyVO vo) {
        if (ObjectUtils.isEmpty(vo.getZjApplyId())) {
            throw new AppException("传入需要修改的主键不能为空!");
        }
        EduSyncZjApply oldEntity = eduSyncZjApplyService.getById(vo.getZjApplyId());
        if (ObjectUtils.isEmpty(oldEntity)) {
            throw new AppException("查询不到需要修改的信息!");
        }
        //保存前校验
        //保存数据
        EduSyncZjApply entity = Convert.convert(EduSyncZjApply.class, vo);
        eduSyncZjApplyService.updateById(entity);
        return vo;
    }

    @Override
    @OpApi(funcCode = "eduSyncZj0006", title = "省招生报名专库同步管理-报名数据同步根据主键删除", funcType = FuncTypeEnum.delete)
    @SaveOplog(
            operationType = "eduSyncZj0006",
            operationName = "省招生报名专库同步管理-报名数据同步删除",
            dataType = "zjApplyId",
            auType = AuTypeEnum.OTHER)
    @Transactional
    public void del(EduSyncZjApplyKeyVO vo) {
        if (ObjectUtils.isEmpty(vo.getZjApplyId())) {
            throw new AppException("传入需要删除的数据主键不能为空!");
        }
        EduSyncZjApply entity = eduSyncZjApplyService.getById(vo.getZjApplyId());
        if (ObjectUtils.isEmpty(entity)) {
            throw new AppException("未找到需要删除的信息!");
        }
        eduSyncZjApplyService.removeById(vo.getZjApplyId());
    }

    @Override
    @OpApi(funcCode = "eduSyncZj0022", title = "省招生报名专库同步管理-报名信息同步", funcType = FuncTypeEnum.other)
    @Transactional
    public RecruitStudentSyncRetVO sync(EduSyncZjApplyKeyVO vo) {
        if (vo.getZjApplyId() == null) {
            throw new AppException("需要发送的报名id不能为空!");
        }
        EduSyncZjApply entity = eduSyncZjApplyService.getById(vo.getZjApplyId());
        if (entity == null) {
            throw new AppException("需要发送的报名信息不存在!");
        }
        if ("1".equalsIgnoreCase(entity.getSyncStatus())) {
            throw new AppException("已发送成功不能重复发送!");
        }
        //获取appKey
        CommonVO urlVO = new CommonVO();
        urlVO.setParamKey("edu_zj_sync_apply_url");
        String url = commonIntegration.getValueByKey(urlVO);
        if (StringUtils.isBlank(url)) {
            throw new AppException("请先在系统中配置配置省报名库报名专库地址edu_zj_sync_apply_url");
        }
        EduSyncZjApplyReq req = Convert.convert(EduSyncZjApplyReq.class, entity);
        req.setMasterGuardianIdNumber(entity.getMasterGuardianNumber());
        req.setSlaveGuardianIdNumber(entity.getSlaveGuardianNumber());
        RecruitStudentSyncRetVO retVO = eduSyncZjUtil.send(url, JSON.toJSONString(req),entity.getApplyCountyCode());
        if ("200".equalsIgnoreCase(retVO.getCode())) {
            entity.setSyncStatus("1");
            entity.setSyncMsg("调用成功");
            entity.setBusinessCode(retVO.getData() != null ? retVO.getData().getBusinessCode() : "");
        } else {
            entity.setSyncStatus("2");
            if (StringUtils.isNotBlank(retVO.getMsg())) {
                if (retVO.getMsg().length() < 300) {
                    entity.setSyncMsg(retVO.getMsg());
                } else {
                    entity.setSyncMsg(retVO.getMsg().substring(0, 300));
                }
            } else {
                entity.setSyncMsg(retVO.getMsg());
            }

        }
        entity.setSyncTime(new Date());
        eduSyncZjApplyService.updateById(entity);
        return retVO;
    }

    @Override
    @OpApi(funcCode = "eduSyncZj0026", title = "省招生报名专库同步管理-报名信息生成", funcType = FuncTypeEnum.insert)
    @Async("commonTaskExecutor")
    public void create(SyncStudentQueryVO vo) {
        String redisKey = "edu:zjSync:create:apply";
        if (redisHelper.hasKey(redisKey)) {
            throw new AppException("正在执行中");
        }
        redisHelper.set(redisKey, true, 3600);
        vo.setYear(eduHelper.thisYear());
        // 开启分页
        if (vo.getPageNum() == null || vo.getPageSize() == null) {
            //如果不传入分页参数，默认最大取200条
            vo.setPageNum(1);
            vo.setPageSize(200);
        }
        if (StringUtils.isBlank(vo.getAreaCode())) {
            vo.setAreaCode(SessionUtil.getAreaCode());
        }
        if (StringUtils.isBlank(vo.getAreaCode())) {
            vo.setAreaCode(eduHelper.thisAreaCode());
        }
        if (StringUtils.isBlank(vo.getEnrollStatus())) {
            vo.setEnrollStatus(EnrollStatusFormalEnum.lq.getType());
        }
        try {
            createDo(vo);
        } catch (Exception e) {
            redisHelper.del(redisKey);
            e.printStackTrace();
        }
    }

    public void createDo(SyncStudentQueryVO vo) {
        String redisKey = "edu:zjSync:create:apply";

        //PageHelper.startPage(vo.getPageNum(), vo.getPageSize());
        List<SyncStudentVO> enrollList = eduSyncZjApplyService.queryNoCreate(vo);
        if (CollectionUtils.isEmpty(enrollList)) {
            redisHelper.del(redisKey);
            return;
        }
        // 不为空则获取分页结果
        //PageInfo<SyncStudentVO> pageInfo = new PageInfo<>(enrollList);
        List<EduSyncZjApply> saveList = new ArrayList<>();
        for (SyncStudentVO syncStudentVO : enrollList) {
            EduSyncZjApply entity = new EduSyncZjApply();
            entity.setName(syncStudentVO.getFullName());
            entity.setIdNumber(syncStudentVO.getIdcard());
            if (CardTypeEnum.idcard.getType().equalsIgnoreCase(syncStudentVO.getCardType())) {
                entity.setIdType("31");//身份证
            } else {
                entity.setIdType("35");//统一用港澳通行证
            }
            entity.setTheYear(syncStudentVO.getYear());
            entity.setSyncStatus("0");
            entity.setApplyCountyCode(syncStudentVO.getAreaCode());
            entity.setCensusRegisterAddr(syncStudentVO.getHouseholdPlace());//户籍地址
            entity.setCensusRegisterType("1");
            if ("1".equalsIgnoreCase(syncStudentVO.getSex())) {
                entity.setSex("0");
            } else {
                entity.setSex("1");
            }
            if (SchoolCategoryEnum.PRIMARY.getType().equalsIgnoreCase(syncStudentVO.getSchoolCategory())) {
                entity.setStage("576");
            } else {
                entity.setStage("577");
            }
            entity.setResidentialAddress(syncStudentVO.getAddress());//居住地址
            entity.setApplyTime(syncStudentVO.getCreateTime().getTime());//报名时间

            if (StringUtils.isNotBlank(syncStudentVO.getFatherIdcard())) {
                entity.setMasterGuardianName(syncStudentVO.getFatherName());
                entity.setMasterGuardianNumber(syncStudentVO.getFatherIdcard());
                entity.setMasterGuardianRelation("1");//父亲
                if (StringUtils.isNotBlank(syncStudentVO.getMotherIdcard())) {
                    entity.setSlaveGuardianName(syncStudentVO.getMotherName());
                    entity.setSlaveGuardianNumber(syncStudentVO.getMotherIdcard());
                    entity.setSlaveGuardianRelation("2");//母亲
                }
            } else {
                entity.setMasterGuardianName(syncStudentVO.getMotherName());
                entity.setMasterGuardianNumber(syncStudentVO.getMotherIdcard());
                entity.setMasterGuardianRelation("2");//母亲
            }
            eduSyncZjApplyService.save(entity);
        }
        redisHelper.del(redisKey);
    }

    @Override
    @OpApi(funcCode = "eduSyncZj0027", title = "省招生报名专库同步管理-报名信息批量同步", funcType = FuncTypeEnum.other)
    @Async("commonTaskExecutor")
    public void batchSync(EduSyncZjApplyQueryVO vo) {
        String redisKey = "edu:zjSync:send:apply";
        if (redisHelper.hasKey(redisKey)) {
            throw new AppException("正在执行中");
        }
        redisHelper.set(redisKey, true, 3600);
        // 开启分页
        if (vo.getPageNum() == null || vo.getPageSize() == null) {
            //如果不传入分页参数，默认最大取1000条
            vo.setPageNum(1);
            vo.setPageSize(1000);
        }
        vo.setTheYear(eduHelper.thisYear());
        if (StringUtils.isBlank(vo.getApplyCountyCode())) {
            vo.setApplyCountyCode(SessionUtil.getAreaCode());
        }
        if (StringUtils.isBlank(vo.getApplyCountyCode())) {
            vo.setApplyCountyCode(eduHelper.thisAreaCode());
        }
        if (StringUtils.isBlank(vo.getSyncStatus())) {
            vo.setSyncStatus("0");
        }
        try {
            batchSyncDo(vo);
        } catch (Exception e) {
            redisHelper.del(redisKey);
            e.printStackTrace();
        }

    }

    @Override
    @OpApi(funcCode = "eduSyncZj0033", title = "省招生报名专库同步管理-清除处理缓存", funcType = FuncTypeEnum.other)
    public void clearCache(BaseVO vo) {
        redisHelper.del("edu:zjSync:create:apply");
        redisHelper.del("edu:zjSync:send:apply");
        redisHelper.del("edu:zjSync:create:approve");
        redisHelper.del("edu:zjSync:send:approve");
        redisHelper.del("edu:zjSync:create:enroll");
        redisHelper.del("edu:zjSync:send:enroll");
        redisHelper.del("edu:zjSync:send:delete");
    }

    @Override
    @OpApi(funcCode = "eduSyncZj0034", title = "省招生报名专库同步管理-批量生成报名数据", funcType = FuncTypeEnum.insert)
    @Transactional(rollbackFor = {AppException.class, DataIntegrityViolationException.class})
    public void batchCreateApply(EduSyncZjApplyQueryVO vo) {
        String redisKey = "edu:zjSync:create:apply";
        if (redisHelper.hasKey(redisKey)){
            throw new AppException("报名数据正在处理中.......");
        }
        redisHelper.set(redisKey,"1",1800);
        try {
            if (StringUtils.isEmpty(vo.getSyncType()) || !"1".equals(vo.getSyncType())){
                //默认增量同步
                vo.setSyncType("2");
            }
            Integer year = eduHelper.thisYear();
            List<EduStudentEnroll> enrollList = getEnrollList(vo.getSyncType(),year,"1");
            if (CollectionUtils.isEmpty(enrollList)){
                return;
            }
            List<String> idCardsToQuery = enrollList.stream()
                    .filter(enroll -> StringUtils.isNotBlank(enroll.getIdcard()))
                    .map(EduStudentEnroll::getIdcard)
                    .collect(Collectors.toList());
            // 构建批量查询条件
            QueryWrapper<EduSyncZjApply> batchQuery = new QueryWrapper<>();
            batchQuery.lambda().select(EduSyncZjApply::getZjApplyId,EduSyncZjApply::getIdNumber).in(EduSyncZjApply::getIdNumber, idCardsToQuery)
                    .eq(EduSyncZjApply::getTheYear, year);
            List<EduSyncZjApply> applyList = eduSyncZjApplyService.list(batchQuery);
            Map<String, Long> applyMap = new HashMap<>();
            applyMap= applyList.stream()
                    .collect(Collectors.toMap(EduSyncZjApply::getIdNumber, EduSyncZjApply::getZjApplyId));
            // 使用HashSet优化性能
            Set<String> idcards = new HashSet<>();
            List<EduSyncZjApply> toSaveOrUpdateList = new ArrayList<>();
            for (EduStudentEnroll enroll : enrollList) {
                if (StringUtils.isNotBlank(enroll.getIdcard())){
                    if (idcards.contains(enroll.getIdcard())){
                        continue;
                    }
                    idcards.add(enroll.getIdcard());
                }
                EduSyncZjApply eduSyncZjApply = new EduSyncZjApply();
                Long zjApplyId = applyMap.get(enroll.getIdcard());
                if (zjApplyId != null){
                    eduSyncZjApply.setZjApplyId(zjApplyId);
                }
                initSyncApply(eduSyncZjApply,enroll);
                toSaveOrUpdateList.add(eduSyncZjApply);
            }
            // 执行批处理
            int batchSize = 1000;
            for (int i = 0; i < toSaveOrUpdateList.size(); i += batchSize) {
                int end = Math.min(i + batchSize, toSaveOrUpdateList.size());
                List<EduSyncZjApply> subList = toSaveOrUpdateList.subList(i, end);
                eduSyncZjApplyService.saveOrUpdateBatch(subList);
            }
        }catch (AppException e){
            throw new AppException("批量生成同步到省报名库数据系统异常"+e.getMessage(),e);
        }catch (Exception e){
            throw new AppException("发生未预期的错误"+e.getMessage(),e);
        }finally {
            redisHelper.del(redisKey);
        }
    }

    @Override
    @OpApi(funcCode = "eduSyncZj0035", title = "省招生审核专库同步管理-批量生成审核数据", funcType = FuncTypeEnum.insert)
    @Transactional(rollbackFor = {AppException.class, DataIntegrityViolationException.class})
    public void batchCreateApprove(EduSyncZjApproveQueryVO vo) {
        String redisKey = "edu:zjSync:create:approve";
        if (redisHelper.hasKey(redisKey)){
            throw new AppException("审核数据正在处理中.......");
        }
        redisHelper.set(redisKey,"1",1800);
        try{
            if (StringUtils.isEmpty(vo.getSyncType()) || !"1".equals(vo.getSyncType())){
                vo.setSyncType("2");
            }
            Integer year = eduHelper.thisYear();
            List<EduStudentEnroll> enrollList = getEnrollList(vo.getSyncType(), year,"2");
            if (CollectionUtils.isEmpty(enrollList)){
                return;
            }
            List<String> idcardQuery = enrollList.stream()
                    .filter(enroll ->StringUtils.isNotBlank(enroll.getIdcard()))
                    .map(EduStudentEnroll::getIdcard).distinct().collect(Collectors.toList());
            QueryWrapper<EduSyncZjApprove> approveQueryWrapper = new QueryWrapper<>();
            approveQueryWrapper.lambda().select(EduSyncZjApprove::getIdNumber,EduSyncZjApprove::getZjApproveId)
                    .eq(EduSyncZjApprove::getTheYear,year)
                    .in(EduSyncZjApprove::getIdNumber,idcardQuery);
            List<EduSyncZjApprove> approveList = approveService.list(approveQueryWrapper);
            Map<String, String> approveMap = new HashMap<>();
            approveList.forEach(approve -> approveMap.put(approve.getIdNumber(),approve.getZjApproveId()));

            QueryWrapper<EduSyncZjApply> applyQueryWrapper = new QueryWrapper<>();
            applyQueryWrapper.lambda().select(EduSyncZjApply::getIdNumber,EduSyncZjApply::getZjApplyId)
                    .eq(EduSyncZjApply::getTheYear,year)
                    .in(EduSyncZjApply::getIdNumber,idcardQuery);
            List<EduSyncZjApply> applyList = eduSyncZjApplyService.list(applyQueryWrapper);
            Map<String, Long> applyMap = new HashMap<>();
            applyMap = applyList.stream().collect(Collectors.toMap(EduSyncZjApply::getIdNumber, EduSyncZjApply::getZjApplyId));
            Set<String>idcardMap = new HashSet<>();
            List<EduSyncZjApprove> toSaveOrUpdateList = new ArrayList<>();
            for (EduStudentEnroll eduStudentEnroll : enrollList) {
                EduSyncZjApprove approve = new EduSyncZjApprove();
                if (StringUtils.isNotBlank(eduStudentEnroll.getIdcard())){
                    if (idcardMap.contains(eduStudentEnroll.getIdcard())){
                        continue;
                    }
                    idcardMap.add(eduStudentEnroll.getIdcard());
                }
                if (approveMap.containsKey(eduStudentEnroll.getIdcard())){
                    String approveId = approveMap.get(eduStudentEnroll.getIdcard());
                    approve.setZjApproveId(approveId);
                }
                Long zjApplyId = applyMap.get(eduStudentEnroll.getIdcard());
                if (zjApplyId == null){
                    throw new AppException(eduStudentEnroll.getFullName()+"报名数据未同步到省报名库，数据异常！暂停同步");
                }
                approve.setZjApplyId(zjApplyId);
                initSyncApprove(approve,eduStudentEnroll);
                toSaveOrUpdateList.add(approve);
            }
            // 执行批处理
            int batchSize = 1000;
            for (int i = 0; i < toSaveOrUpdateList.size(); i += batchSize) {
                int end = Math.min(i + batchSize, toSaveOrUpdateList.size());
                List<EduSyncZjApprove> subList = toSaveOrUpdateList.subList(i, end);
                approveService.saveOrUpdateBatch(subList);
            }
        }catch (AppException e){
            throw new AppException("批量生成同步到省审核库数据系统异常"+e.getMessage(),e);
        }catch (Exception e){
            throw new AppException("发生未预期的错误"+e.getMessage(),e);
        }finally {
            redisHelper.del(redisKey);
        }
    }


    @Override
    @OpApi(funcCode = "eduSyncZj0036", title = "省招生录取专库同步管理-批量生成录取数据", funcType = FuncTypeEnum.insert)
    @Transactional(rollbackFor = {AppException.class, DataIntegrityViolationException.class})
    public void batchCreateEnroll(EduSyncZjEnrollQueryVO vo) {
        String redisKey = "edu:zjSync:create:enroll";
        if (redisHelper.hasKey(redisKey)){
            throw new AppException("录取数据正在处理中.......");
        }
        redisHelper.set(redisKey,"1",1800);
        try{
            if (StringUtils.isEmpty(vo.getSyncType()) || !"1".equals(vo.getSyncType())){
                vo.setSyncType("2");
            }
            Integer year = eduHelper.thisYear();
            List<EduStudentEnroll> enrollList = getEnrollList(vo.getSyncType(), year,"3");
            if (CollectionUtils.isEmpty(enrollList)){
                return;
            }
            List<String> idcardQuery = enrollList.stream()
                    .filter(enroll ->(StringUtils.isNotBlank(enroll.getIdcard())))
                    .map(EduStudentEnroll::getIdcard).distinct().collect(Collectors.toList());

            //查询审核数据
            QueryWrapper<EduSyncZjApprove> approveQueryWrapper = new QueryWrapper<>();
            approveQueryWrapper.lambda().select(EduSyncZjApprove::getIdNumber,EduSyncZjApprove::getZjApplyId)
                    .eq(EduSyncZjApprove::getTheYear,year)
                    .in(EduSyncZjApprove::getIdNumber,idcardQuery);
            List<EduSyncZjApprove> approveList = approveService.list(approveQueryWrapper);
            Map<String, Long> approveMap = new HashMap<>();
            approveList.forEach(approve -> approveMap.put(approve.getIdNumber(),approve.getZjApplyId()));

            QueryWrapper<EduSyncZjEnroll> enrollQueryWrapper = new QueryWrapper<>();
            enrollQueryWrapper.lambda().select(EduSyncZjEnroll::getIdNumber,EduSyncZjEnroll::getZjEnrollId)
                    .eq(EduSyncZjEnroll::getTheYear,year)
                    .in(EduSyncZjEnroll::getIdNumber,idcardQuery);
            List<EduSyncZjEnroll> syncZjEnrolls = syncZjEnrollService.list(enrollQueryWrapper);
            Map<String, String> enrollMap = new HashMap<>();
            enrollMap = syncZjEnrolls.stream().collect(Collectors.toMap(EduSyncZjEnroll::getIdNumber, EduSyncZjEnroll::getZjEnrollId));
            List<EduSyncZjEnroll> toSaveOrUpdateList = new ArrayList<>();
            Set<String>idcardMap = new HashSet<>();
            for (EduStudentEnroll eduStudentEnroll : enrollList) {
                EduSyncZjEnroll eduSyncZjEnroll = new EduSyncZjEnroll();
                if (StringUtils.isNotBlank(eduStudentEnroll.getIdcard())){
                    if (idcardMap.contains(eduStudentEnroll.getIdcard())){
                        continue;
                    }
                    idcardMap.add(eduStudentEnroll.getIdcard());
                }

                if (enrollMap.containsKey(eduStudentEnroll.getIdcard())){
                    String zjEnrollId = enrollMap.get(eduStudentEnroll.getIdcard());
                    eduSyncZjEnroll.setZjEnrollId(zjEnrollId);
                }
                Long zjApplyId = approveMap.get(eduStudentEnroll.getIdcard());
                if (zjApplyId == null){
                    throw new AppException(eduStudentEnroll.getFullName()+"审核数据未同步到省审核库，数据异常！暂停同步");
                }
                eduSyncZjEnroll.setZjApplyId(zjApplyId);
                initSyncEnroll(eduSyncZjEnroll,eduStudentEnroll);
                toSaveOrUpdateList.add(eduSyncZjEnroll);
            }
            // 执行批处理
            int batchSize = 1000;
            for (int i = 0; i < toSaveOrUpdateList.size(); i += batchSize) {
                int end = Math.min(i + batchSize, toSaveOrUpdateList.size());
                List<EduSyncZjEnroll> subList = toSaveOrUpdateList.subList(i, end);
                syncZjEnrollService.saveOrUpdateBatch(subList);
            }
        }catch (AppException e){
            throw new AppException("批量生成同步到省录取库数据系统异常"+e.getMessage(),e);
        }catch (Exception e){
            throw new AppException("发生未预期的错误"+e.getMessage(),e);
        }finally {
            redisHelper.del(redisKey);
        }
    }


    @Override
    @OpApi(funcCode = "eduSyncZj0037", title = "省招生专库同步管理-批量同步删除数据", funcType = FuncTypeEnum.insert)
    @Transactional(rollbackFor = {AppException.class, DataIntegrityViolationException.class})
    public void batchCreateDelete(EduSyncZjDeleteQueryVO vo) {
        String redisKey = "edu:zjSync:create:delete";
        if (redisHelper.hasKey(redisKey)){
            throw new AppException("数据正在处理中.......");
        }
        redisHelper.set(redisKey,"1",1800);
        try {
            if (StringUtils.isEmpty(vo.getSyncType()) || !"1".equals(vo.getSyncType())){
                vo.setSyncType("2");
            }
            Integer year = eduHelper.thisYear();
            //查询需要同步到删除表的数据
            List<EduSyncZjApply> syncApplyList = getSyncDeleteEnrollList(year,vo.getSyncType());
            if (CollectionUtils.isEmpty(syncApplyList)){
                return;
            }
            //提取身份证号码
            List<String> idcardQuery = syncApplyList.stream()
                    .filter(enroll ->(StringUtils.isNotBlank(enroll.getIdNumber())))
                    .map(EduSyncZjApply::getIdNumber).distinct().collect(Collectors.toList());
            //根据身份证，查询同步删除表
            QueryWrapper<EduSyncZjDelete> deleteQueryWrapper = new QueryWrapper<>();
            deleteQueryWrapper.lambda().select(EduSyncZjDelete::getIdNumber,EduSyncZjDelete::getZjDeleteId,EduSyncZjDelete::getDeleteType,EduSyncZjDelete::getDeleteId)
                    .eq(EduSyncZjDelete::getTheYear,year)
                    .in(EduSyncZjDelete::getIdNumber,idcardQuery);
            List<EduSyncZjDelete> syncZjDeleteList = syncZjDeleteService.list(deleteQueryWrapper);

            //报名表
            Map<String, EduSyncZjDelete> applyDeleteMap = syncZjDeleteList.stream()
                    .filter(delete ->"1".equals(delete.getDeleteType()))
                    .collect(Collectors.toMap(EduSyncZjDelete::getIdNumber, Function.identity()));
            QueryWrapper<EduSyncZjApply> applyQueryWrapper = new QueryWrapper<>();
            applyQueryWrapper.lambda().select(EduSyncZjApply::getIdNumber,EduSyncZjApply::getZjApplyId)
                    .in(EduSyncZjApply::getIdNumber,idcardQuery)
                    .eq(EduSyncZjApply::getTheYear,year);
            List<EduSyncZjApply> syncZjApplyList = eduSyncZjApplyService.list(applyQueryWrapper);
            Map<String, Long> applyMap = syncZjApplyList.stream().collect(Collectors.toMap(EduSyncZjApply::getIdNumber, EduSyncZjApply::getZjApplyId));


            //审核表
            Map<String, EduSyncZjDelete> approveDeleteMap = syncZjDeleteList.stream()
                    .filter(delete ->"2".equals(delete.getDeleteType()))
                    .collect(Collectors.toMap(EduSyncZjDelete::getIdNumber, Function.identity()));
            QueryWrapper<EduSyncZjApprove> approveQueryWrapper = new QueryWrapper<>();
            approveQueryWrapper.lambda().select(EduSyncZjApprove::getIdNumber,EduSyncZjApprove::getZjApproveId)
                    .in(EduSyncZjApprove::getIdNumber,idcardQuery)
                    .eq(EduSyncZjApprove::getTheYear,year);
            List<EduSyncZjApprove> syncZjApproveList = approveService.list(approveQueryWrapper);
            Map<String, String> approveMap = syncZjApproveList.stream().collect(Collectors.toMap(EduSyncZjApprove::getIdNumber, EduSyncZjApprove::getZjApproveId));

            //录取表
            Map<String, EduSyncZjDelete> enrollDeleteMap = syncZjDeleteList.stream()
                    .filter(delete ->"3".equals(delete.getDeleteType()))
                    .collect(Collectors.toMap(EduSyncZjDelete::getIdNumber,Function.identity()));
            QueryWrapper<EduSyncZjEnroll> syncEnrollQueryWrapper =  new QueryWrapper<>();
            syncEnrollQueryWrapper.lambda().select(EduSyncZjEnroll::getIdNumber,EduSyncZjEnroll::getZjEnrollId)
                    .in(EduSyncZjEnroll::getIdNumber,idcardQuery)
                    .eq(EduSyncZjEnroll::getTheYear,year);
            List<EduSyncZjEnroll> syncZjEnrollList = syncZjEnrollService.list(syncEnrollQueryWrapper);
            Map<String, String> enrollMap = syncZjEnrollList.stream()
                    .collect(Collectors.toMap(EduSyncZjEnroll::getIdNumber, EduSyncZjEnroll::getZjEnrollId));

            //创建一个要处理的列表
            List<EduSyncZjDelete> toSaveOrUpdateList = new ArrayList<>();
            Set<String>idcardMap = new HashSet<>();
            for (EduSyncZjApply eduSyncZjApply  : syncApplyList) {
                if (StringUtils.isNotBlank(eduSyncZjApply.getIdNumber())){
                    if (idcardMap.contains(eduSyncZjApply.getIdNumber())){
                        continue;
                    }
                    idcardMap.add(eduSyncZjApply.getIdNumber());
                }
                EduSyncZjDelete syncZjEnroll = new EduSyncZjDelete();
                //录取表是否有
                if (enrollDeleteMap.containsKey(eduSyncZjApply.getIdNumber())){
                    EduSyncZjDelete syncZjDelete = enrollDeleteMap.get(eduSyncZjApply.getIdNumber());
                    syncZjEnroll.setZjDeleteId(syncZjDelete.getZjDeleteId());
                    syncZjEnroll.setDeleteId(syncZjDelete.getDeleteId());
                    initSyncDelete(syncZjEnroll,eduSyncZjApply);
                    syncZjEnroll.setDeleteType("3");
                    toSaveOrUpdateList.add(syncZjEnroll);
                }else{
                    if (enrollMap.get(eduSyncZjApply.getIdNumber()) != null){
                        String deleteId = enrollMap.get(eduSyncZjApply.getIdNumber());
                        syncZjEnroll.setDeleteId(Long.valueOf(deleteId));
                        initSyncDelete(syncZjEnroll,eduSyncZjApply);
                        syncZjEnroll.setDeleteType("3");
                        toSaveOrUpdateList.add(syncZjEnroll);
                    }
                }


                EduSyncZjDelete syncZjApprove = new EduSyncZjDelete();
                //审核表是否有
                if (approveDeleteMap.containsKey(eduSyncZjApply.getIdNumber())){
                    EduSyncZjDelete syncZjDelete = approveDeleteMap.get(eduSyncZjApply.getIdNumber());
                    syncZjApprove.setZjDeleteId(syncZjDelete.getZjDeleteId());
                    syncZjApprove.setDeleteId(syncZjDelete.getDeleteId());
                    initSyncDelete(syncZjApprove,eduSyncZjApply);
                    syncZjApprove.setDeleteType("2");
                    toSaveOrUpdateList.add(syncZjApprove);
                }else{
                    if (approveMap.get(eduSyncZjApply.getIdNumber()) != null){
                        String deleteId = approveMap.get(eduSyncZjApply.getIdNumber());
                        syncZjApprove.setDeleteId(Long.valueOf(deleteId));
                        initSyncDelete(syncZjApprove,eduSyncZjApply);
                        syncZjApprove.setDeleteType("2");
                        toSaveOrUpdateList.add(syncZjApprove);
                    }
                }


                EduSyncZjDelete syncZjApply = new EduSyncZjDelete();
                //报名表是否有
                if (applyDeleteMap.containsKey(eduSyncZjApply.getIdNumber())){
                    EduSyncZjDelete syncZjDelete = applyDeleteMap.get(eduSyncZjApply.getIdNumber());
                    syncZjApply.setZjDeleteId(syncZjDelete.getZjDeleteId());
                    syncZjApply.setDeleteId(syncZjDelete.getDeleteId());
                    initSyncDelete(syncZjApply,eduSyncZjApply);
                    syncZjApply.setDeleteType("1");
                    toSaveOrUpdateList.add(syncZjApply);
                }else{
                    if (applyMap.get(eduSyncZjApply.getIdNumber()) != null){
                        Long deleteId = applyMap.get(eduSyncZjApply.getIdNumber());
                        syncZjApply.setDeleteId(deleteId);
                        initSyncDelete(syncZjApply,eduSyncZjApply);
                        syncZjApply.setDeleteType("1");
                        toSaveOrUpdateList.add(syncZjApply);
                    }
                }

            }
            // 执行批处理
            int batchSize = 1000;
            for (int i = 0; i < toSaveOrUpdateList.size(); i += batchSize) {
                int end = Math.min(i + batchSize, toSaveOrUpdateList.size());
                List<EduSyncZjDelete> subList = toSaveOrUpdateList.subList(i, end);
                syncZjDeleteService.saveOrUpdateBatch(subList);
            }
        }catch (AppException e){
            throw new AppException("批量生成同步到省录取库数据系统异常"+e.getMessage(),e);
        }catch (Exception e){
            throw new AppException("发生未预期的错误"+e.getMessage(),e);
        }finally {
            redisHelper.del(redisKey);
        }
    }

    @Override
    @OpApi(
            funcCode = "eduSyncZj0038",
            title = "省招生专库同步管理-报名excel导出",
            funcType = FuncTypeEnum.other)
    @NoSignCrypto
    public void exportZJApplyInfo(EduSyncZjApplyQueryVO vo, HttpServletResponse response) {
        if (ObjectUtils.isEmpty(vo.getModelCode())) {
            throw new AppException("请传入模板编码!  ");
        }
        if (StringUtils.isBlank(vo.getExportTable())){
            throw new AppException("请输入导出的表名!  ");
        }
        ExcelVO excelVO = new ExcelVO();
        excelVO.setModelCode(vo.getModelCode());
        ExcelModelVO excelModelVO = excelIntegration.getModel(excelVO);
        String destFilePath = this.tempPath + "/" + IdUtil.fastSimpleUUID() + "." + excelModelVO.getExcelType();
        int pageNum = 1;
        setDataApply(excelModelVO, null, destFilePath, vo, pageNum);
        String fileName =DateUtil.today();
        if ("apply".equals(vo.getExportTable())){
            fileName = "金华市报名同步数据" + DateUtil.today();
        }else if ("enroll".equals(vo.getExportTable())){
            fileName = "金华市录取同步数据" + DateUtil.today();
        }else if ("approve".equals(vo.getExportTable())){
            fileName = "金华市审核同步数据" + DateUtil.today();
        }
        if (StringUtils.isBlank(fileName)) {
            fileName =
                    excelModelVO.getModelName()
                            + "_"
                            + DateUtil.format(DateUtil.date(), DatePattern.PURE_DATETIME_PATTERN)
                            + "."
                            + (StringUtils.isBlank(excelModelVO.getExcelType())
                            ? "xls"
                            : excelModelVO.getExcelType());
        }
        File file = FileUtil.file(destFilePath);
        BufferedInputStream in = null;
        try {
            in = FileUtil.getInputStream(file);
            ServletUtil.write(response, in, "application/octet-stream;charset=utf-8", fileName);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            FileUtil.del(destFilePath);
        }
    }

    /**
     * 省报名模板下载
     * @param vo
     * @param response
     */
    @Override
    @OpApi(funcCode = "eduSyncZj0039", title = "省招生专库同步管理-报名模板下载",
            funcType = FuncTypeEnum.other, checkPrivilege = BoolEnum.FALSE)
    public void downloadModel(ExcelVO vo, HttpServletResponse response) {
        ExcelModelVO excelModelVO=excelIntegration.getModel(vo);
        excelCommonHelper.downloadModel(excelModelVO,vo.getRows(),response);
    }



    private void setDataApply(ExcelModelVO excelModelVO, ExcelWriter excelWriter, String destFilePath, EduSyncZjApplyQueryVO vo, int pageNum) {
        vo.setPageNum(pageNum);
        vo.setPageSize(500);
        boolean closeFlag = false;
        try {
            List<Map<String, Object>> list = new ArrayList<>();
            boolean hasNextPage = false;
            String total = "0";
            if ("apply".equals(vo.getExportTable())){
                PageInfo<EduSyncZjApplyVO> pageInfo = getList(vo);
                hasNextPage = pageInfo.isHasNextPage();
                total = String.valueOf(pageInfo.getTotal());
                if (!CollectionUtils.isEmpty(pageInfo.getList())) {
                    for (EduSyncZjApplyVO syncZJApplyVO : pageInfo.getList()) {
                        list.add(BeanUtil.beanToMap(syncZJApplyVO, false, true));
                    }
                }
            }else if ("approve".equals(vo.getExportTable())){
                EduSyncZjApproveQueryVO eduSyncZjApproveQueryVO = new EduSyncZjApproveQueryVO();
                BeanUtils.copyProperties(vo,eduSyncZjApproveQueryVO);
                PageInfo<EduSyncZjApproveVO> pageInfo = approveIntegration.getList(eduSyncZjApproveQueryVO);
                hasNextPage = pageInfo.isHasNextPage();
                total = String.valueOf(pageInfo.getTotal());
                if (!CollectionUtils.isEmpty(pageInfo.getList())) {
                    for (EduSyncZjApproveVO syncZJApprove : pageInfo.getList()) {
                        list.add(BeanUtil.beanToMap(syncZJApprove, false, true));
                    }
                }
            } else if ("enroll".equals(vo.getExportTable())){
                EduSyncZjEnrollQueryVO eduSyncZjEnrollQueryVO = new EduSyncZjEnrollQueryVO();
                BeanUtils.copyProperties(vo,eduSyncZjEnrollQueryVO);
                PageInfo<EduSyncZjEnrollVO> pageInfo = eduSyncZjEnrollIntegration.getList(eduSyncZjEnrollQueryVO);
                hasNextPage = pageInfo.isHasNextPage();
                total = String.valueOf(pageInfo.getTotal());
                if (!CollectionUtils.isEmpty(pageInfo.getList())) {
                    for (EduSyncZjEnrollVO syncZJEnroll : pageInfo.getList()) {
                        list.add(BeanUtil.beanToMap(syncZJEnroll, false, true));
                    }
                }
            }

            if (pageNum == 1) {
                if (excelWriter == null) {
                    excelWriter = excelCommonHelper.createExcelWriter(excelModelVO, destFilePath, Integer.parseInt(total));
                }
                excelCommonHelper.writeMap(excelWriter, list);
            } else {
                excelCommonHelper.writeMap(excelWriter, list);
            }
            if (hasNextPage) {
                pageNum = pageNum + 1;
                setDataApply(excelModelVO, excelWriter, destFilePath, vo, pageNum);
            } else {
                closeFlag = true;
            }
        } catch (AppException appEx) {
            throw appEx;
        } catch (Exception e) {
            throw new AppException("调用自定义写入服务异常:" + e.getMessage());
        } finally {
            if (closeFlag && excelWriter != null) {
                excelWriter.close();
            }
        }
    }


    /**
     * 初始化删除表数据
     * @param syncZjDelete
     * @param eduSyncZjApply
     */
    private void initSyncDelete(EduSyncZjDelete syncZjDelete, EduSyncZjApply eduSyncZjApply) {
        syncZjDelete.setTheYear(eduSyncZjApply.getTheYear());
        syncZjDelete.setStage(eduSyncZjApply.getStage());
        syncZjDelete.setName(eduSyncZjApply.getName());
        syncZjDelete.setIdType(eduSyncZjApply.getIdType());
        syncZjDelete.setIdNumber(eduSyncZjApply.getIdNumber());
        syncZjDelete.setApplyCountyCode(eduSyncZjApply.getApplyCountyCode());
        syncZjDelete.setSyncStatus("0");
        syncZjDelete.setSyncMsg(null);
        syncZjDelete.setSyncTime(null);
    }


    /**
     * 获取需要同步到删除表的数据
     *
     * @param year
     * @param syncType
     * @return
     */
    private List<EduSyncZjApply> getSyncDeleteEnrollList(Integer year, String syncType) {
        List<EduSyncZjApply> syncEnrollList =  syncZjEnrollService.getSyncDeleteEnrollList(year,syncType);
        return syncEnrollList;
    }

    private void initSyncEnroll(EduSyncZjEnroll eduSyncZjEnroll, EduStudentEnroll eduStudentEnroll) {
        eduSyncZjEnroll.setTheYear(eduStudentEnroll.getYear());
        if (SchoolCategoryEnum.PRIMARY.getType().equals(eduStudentEnroll.getSchoolCategory())){
            eduSyncZjEnroll.setStage("576");
        } else if (SchoolCategoryEnum.JUNIOR.getType().equals(eduStudentEnroll.getSchoolCategory())) {
            eduSyncZjEnroll.setStage("577");
        }
        eduSyncZjEnroll.setName(eduStudentEnroll.getFullName());
        if (CardTypeEnum.idcard.getType().equalsIgnoreCase(eduStudentEnroll.getCardType())) {
            eduSyncZjEnroll.setIdType("31");//身份证
        } else {
            eduSyncZjEnroll.setIdType("35");//统一用港澳通行证
        }
        eduSyncZjEnroll.setIdNumber(eduStudentEnroll.getIdcard());
        eduSyncZjEnroll.setEnrollState("1");
        eduSyncZjEnroll.setEnrollHuman(eduStudentEnroll.getAdmitUserId());
        if (StringUtils.isBlank(eduSyncZjEnroll.getEnrollHuman())){
            eduSyncZjEnroll.setEnrollHuman(eduStudentEnroll.getSchoolId());
        }
        if (!ObjectUtils.isEmpty(eduStudentEnroll.getAdmitTime())){
            eduSyncZjEnroll.setEnrollTime(eduStudentEnroll.getAdmitTime().getTime());
        }
        eduSyncZjEnroll.setEnrollOpinion(eduStudentEnroll.getAdmitRemarks());
        //根据学校iid，查询学校信息，将省学校代码进行设置
        EduSchoolVO detail = schoolService.getDetail(eduStudentEnroll.getSchoolId());
        if (!ObjectUtils.isEmpty(detail)){
            eduSyncZjEnroll.setEnrollSchoolId(detail.getOrgId());
            eduSyncZjEnroll.setEnrollSchoolCode(detail.getSchoolCodeXj());
            eduSyncZjEnroll.setEnrollSchoolName(detail.getSchoolNameXj());
        }
        eduSyncZjEnroll.setApplyCountyCode(eduStudentEnroll.getAreaCode());
        eduSyncZjEnroll.setSyncStatus("0");
        eduSyncZjEnroll.setSyncMsg(null);
        eduSyncZjEnroll.setSyncTime(null);
        eduSyncZjEnroll.setBusinessCode(null);
    }

    private void initSyncApprove(EduSyncZjApprove approve, EduStudentEnroll eduStudentEnroll) {
        approve.setTheYear(eduHelper.thisYear());
        if (SchoolCategoryEnum.PRIMARY.getType().equals(eduStudentEnroll.getSchoolCategory())){
            approve.setStage("576");
        } else if (SchoolCategoryEnum.JUNIOR.getType().equals(eduStudentEnroll.getSchoolCategory())) {
            approve.setStage("577");
        }
        approve.setName(eduStudentEnroll.getFullName());
        if (CardTypeEnum.idcard.getType().equalsIgnoreCase(eduStudentEnroll.getCardType())) {
            approve.setIdType("31");//身份证
        } else {
            approve.setIdType("35");//统一用港澳通行证
        }
        approve.setIdNumber(eduStudentEnroll.getIdcard());
        approve.setApproveState("1");
        approve.setApproveHuman(eduStudentEnroll.getAuthUserId());
        if (StringUtils.isBlank(approve.getApproveHuman())){
            approve.setApproveHuman(eduStudentEnroll.getSchoolId());
        }
        if (!ObjectUtils.isEmpty(eduStudentEnroll.getAuthTime())){
            approve.setApproveTime(eduStudentEnroll.getAuthTime().getTime());
        }
        approve.setApproveOpinion(eduStudentEnroll.getAuthRemarks());
        approve.setApplyCountyCode(eduStudentEnroll.getAreaCode());
        approve.setBusinessCode(null);
        approve.setSyncStatus("0");
        approve.setSyncMsg(null);
        approve.setSyncTime(null);
    }

    /**
     * 初始化报名数据
     */
    private void initSyncApply(EduSyncZjApply eduSyncZjApply, EduStudentEnroll enroll) {
        eduSyncZjApply.setTheYear(enroll.getYear());
        eduSyncZjApply.setIdNumber(enroll.getIdcard());
        eduSyncZjApply.setName(enroll.getFullName());
        if (SchoolCategoryEnum.PRIMARY.getType().equals(enroll.getSchoolCategory())){
            eduSyncZjApply.setStage("576");
        } else if (SchoolCategoryEnum.JUNIOR.getType().equals(enroll.getSchoolCategory())) {
            eduSyncZjApply.setStage("577");
        }
        eduSyncZjApply.setSex("1".equalsIgnoreCase(enroll.getSex()) ? "0" : "1");
        if (CardTypeEnum.idcard.getType().equalsIgnoreCase(enroll.getCardType())) {
            eduSyncZjApply.setIdType("31");//身份证
        } else {
            eduSyncZjApply.setIdType("35");//统一用港澳通行证
        }
        eduSyncZjApply.setNation("01");
        eduSyncZjApply.setCensusRegisterAddr(enroll.getHouseholdPlace());
        eduSyncZjApply.setCensusRegisterType("1");
        eduSyncZjApply.setResidentialAddress(enroll.getAddress());
        //父亲信息为空，将母亲信息作为主监护人
        if (!StringUtils.isBlank(enroll.getFatherIdcard())){
            eduSyncZjApply.setMasterGuardianName(enroll.getFatherName());
            eduSyncZjApply.setMasterGuardianNumber(enroll.getFatherIdcard());
            eduSyncZjApply.setMasterGuardianRelation("1");
            eduSyncZjApply.setSlaveGuardianName(enroll.getMotherName());
            eduSyncZjApply.setSlaveGuardianNumber(enroll.getMotherIdcard());
            eduSyncZjApply.setSlaveGuardianRelation("2");
        }else{
            eduSyncZjApply.setMasterGuardianName(enroll.getMotherName());
            eduSyncZjApply.setMasterGuardianRelation("2");
            eduSyncZjApply.setMasterGuardianNumber(enroll.getMotherIdcard());
        }
        eduSyncZjApply.setApplyCountyCode(enroll.getAreaCode());
        if (enroll.getCreateTime() != null){
            eduSyncZjApply.setApplyTime(enroll.getCreateTime().getTime());
        }else{
            eduSyncZjApply.setApplyTime(System.currentTimeMillis());
        }
        eduSyncZjApply.setSyncStatus("0");
        eduSyncZjApply.setSyncMsg(null);
        eduSyncZjApply.setSyncTime(null);
    }


    /**
     * 根据同步类型和目标表查询报名信息
     * @param syncType 1.全量同步 2增量同步
     * @param year 年份
     * @param table 1 报名表 2审核表 3录取表
     * @return
     */
    private List<EduStudentEnroll> getEnrollList(String syncType,Integer year,String table) {
        List<EduStudentEnroll> studentEnrolls = new ArrayList<>();
        QueryWrapper<EduStudentEnroll> queryWrapper = new QueryWrapper<>();
        if (("1").equals(table)){
            queryWrapper.lambda().select(
                    EduStudentEnroll::getIdcard,
                    EduStudentEnroll::getYear,
                    EduStudentEnroll::getFullName,
                    EduStudentEnroll::getSchoolCategory,
                    EduStudentEnroll::getCardType,
                    EduStudentEnroll::getAreaCode,
                    EduStudentEnroll::getSex,
                    EduStudentEnroll::getHouseholdPlace,
                    EduStudentEnroll::getAddress,
                    EduStudentEnroll::getSchoolId,
                    EduStudentEnroll::getFatherName,
                    EduStudentEnroll::getFatherIdcard,
                    EduStudentEnroll::getMotherName,
                    EduStudentEnroll::getMotherIdcard,
                    EduStudentEnroll::getCreateTime
            );
            if (("2").equals(syncType)){
                //增量同步，只同步不在报名表的数据
                queryWrapper.lambda().notInSql(EduStudentEnroll::getIdcard,
                        "select id_number from edu_sync_zj_apply where del = '0' and the_year ="+year);
            }
        }
        if ("2".equals(table)){
            //同步审核表时候，报名同步表必须有数据
            queryWrapper.lambda().select(
                    EduStudentEnroll::getIdcard,
                    EduStudentEnroll::getYear,
                    EduStudentEnroll::getFullName,
                    EduStudentEnroll::getSchoolCategory,
                    EduStudentEnroll::getCardType,
                    EduStudentEnroll::getAreaCode,
                    EduStudentEnroll::getSchoolId,
                    EduStudentEnroll::getAuthRemarks,
                    EduStudentEnroll::getAuthTime,
                    EduStudentEnroll::getAuthUserId
            ).inSql(EduStudentEnroll::getIdcard
                    ,"select id_number from edu_sync_zj_apply where del = '0' and the_year ="+year);
            if ("2".equals(syncType)){
                //增量同步，同步不在审核表的数据
                queryWrapper.lambda().notInSql(EduStudentEnroll::getIdcard,
                        "select id_number from edu_sync_zj_approve where del = '0' and the_year ="+year);
            }
        }
        if ("3".equals(table)){
            queryWrapper.lambda().select(
                    EduStudentEnroll::getIdcard,
                    EduStudentEnroll::getYear,
                    EduStudentEnroll::getFullName,
                    EduStudentEnroll::getSchoolCategory,
                    EduStudentEnroll::getCardType,
                    EduStudentEnroll::getAreaCode,
                    EduStudentEnroll::getAdmitUserId,
                    EduStudentEnroll::getAdmitTime,
                    EduStudentEnroll::getAdmitRemarks,
                    EduStudentEnroll::getSchoolId,
                    EduStudentEnroll::getSchoolName
            ).inSql(EduStudentEnroll::getIdcard
                    ,"select id_number from edu_sync_zj_approve where del = '0' and the_year ="+year);
            if ("2".equals(syncType)){
                queryWrapper.lambda().notInSql(EduStudentEnroll::getIdcard,
                        "select id_number from edu_sync_zj_enroll where del = '0' and the_year ="+year);
            }
        }
        queryWrapper.lambda()
                .eq(EduStudentEnroll::getYear,year)
                .eq(EduStudentEnroll::getEnrollStatus,EnrollStatusFormalEnum.lq.getType());
        studentEnrolls = eduStudentEnrollService.list(queryWrapper);
        return studentEnrolls;
    }

    public void batchSyncDo(EduSyncZjApplyQueryVO vo) {
        String redisKey = "edu:zjSync:send:apply";
        QueryWrapper<EduSyncZjApply> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().select(EduSyncZjApply::getZjApplyId).eq(StringUtils.isNotBlank(vo.getApplyCountyCode()), EduSyncZjApply::getApplyCountyCode, vo.getApplyCountyCode())
                .eq(StringUtils.isNotBlank(vo.getIdNumber()), EduSyncZjApply::getIdNumber, vo.getIdNumber())
                .eq(StringUtils.isNotBlank(vo.getName()), EduSyncZjApply::getName, vo.getName())
                .eq(StringUtils.isNotBlank(vo.getIdType()), EduSyncZjApply::getIdType, vo.getIdType())
                .eq(vo.getTheYear() != null, EduSyncZjApply::getTheYear, vo.getTheYear())
                .eq(StringUtils.isNotBlank(vo.getBusinessCode()), EduSyncZjApply::getBusinessCode, vo.getBusinessCode())
                .eq(StringUtils.isNotBlank(vo.getSex()), EduSyncZjApply::getSex, vo.getSex())
                .eq(StringUtils.isNotBlank(vo.getStage()), EduSyncZjApply::getStage, vo.getStage())
                .eq(StringUtils.isNotBlank(vo.getSyncStatus()), EduSyncZjApply::getSyncStatus, vo.getSyncStatus())
                .eq(StringUtils.isNotBlank(vo.getMasterGuardianNumber()), EduSyncZjApply::getMasterGuardianNumber, vo.getMasterGuardianNumber())
                .eq(StringUtils.isNotBlank(vo.getMasterGuardianName()), EduSyncZjApply::getMasterGuardianName, vo.getMasterGuardianName())
                .eq(StringUtils.isNotBlank(vo.getSlaveGuardianName()), EduSyncZjApply::getSlaveGuardianName, vo.getSlaveGuardianName())
                .eq(StringUtils.isNotBlank(vo.getSlaveGuardianNumber()), EduSyncZjApply::getSlaveGuardianNumber, vo.getSlaveGuardianNumber())
                .orderByAsc(EduSyncZjApply::getCreateTime);
        PageHelper.startPage(vo.getPageNum(), vo.getPageSize());
        List<EduSyncZjApply> list = eduSyncZjApplyService.list(queryWrapper);
        if (CollectionUtils.isEmpty(list)) {
            // 判断是否为空，为空则返回空参数
            redisHelper.del(redisKey);
            return;
        }
        // 不为空则获取分页结果
        PageInfo<EduSyncZjApply> pageInfo = new PageInfo<>(list);
        for (EduSyncZjApply eduSyncZjApply : pageInfo.getList()) {
            EduSyncZjApplyKeyVO keyVO = new EduSyncZjApplyKeyVO();
            keyVO.setZjApplyId(eduSyncZjApply.getZjApplyId());
            try {
                this.sync(keyVO);
            } catch (Exception e) {
                log.error("同步省库异常"+e.getMessage(),e);
            }
        }
        redisHelper.del(redisKey);

    }
}